package team.scau.laboratory_repair.service;

import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.EntityPathBase;
import com.querydsl.jpa.impl.JPAQuery;
import lombok.extern.apachecommons.CommonsLog;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import team.scau.laboratory_repair.common.base.BaseService;
import team.scau.laboratory_repair.common.constant.ConstantRole;
import team.scau.laboratory_repair.common.utils.BoxTool;
import team.scau.laboratory_repair.common.utils.StringTool;
import team.scau.laboratory_repair.modules.po.Perm;
import team.scau.laboratory_repair.modules.po.QPerm;
import team.scau.laboratory_repair.modules.po.Role;
import team.scau.laboratory_repair.modules.po.User;
import team.scau.laboratory_repair.modules.repository.PermRepository;

import java.util.*;


/**
 * @author 30254
 * creadtedate:2018/8/19
 */
@Service
@CommonsLog
public class PermService extends BaseService<Perm, PermRepository> {

    @Autowired
    private PermRepository permRepository;

    @Autowired
    private RoleService roleService;

    private QPerm qPerm = QPerm.perm1;

    @Override
    public PermRepository getRepository() {
        return permRepository;
    }

    @Override
    public EntityPathBase<Perm> getQBase() {
        return qPerm;
    }

    public List<Perm> list() throws Exception{
        return queryFactory.select(qPerm).from(qPerm)
                .where(qPerm.valid.eq(true))
                .fetch();
    }

    /**
     * 获取用户的菜单
     * @param cUser
     * @return
     */
    public List<Perm> menu(User cUser) {

        String cPerm = "";

        // 根据角色查询权限
        Long roleId = cUser.getRole();
        if(roleId != null && roleId > 0){
            Role role = roleService.findById(roleId);
            if(role != null) {
                cPerm = role.getPerm();
            }
        }

        if(!ConstantRole.ROLE_SUPER.equals(roleId) && StringUtils.isEmpty(cPerm)){
            return new ArrayList<>();
        }

        //获取用户角色对应的菜单
        JPAQuery<Perm> jpaQuery = queryFactory.select(qPerm).from(qPerm)
                .where(qPerm.valid.eq(true)).where(qPerm.show.eq(true));
        //超级管理员获得所有菜单
        if(!cUser.getRole().equals(ConstantRole.ROLE_SUPER)){
            jpaQuery = jpaQuery.where(qPerm.id.in(BoxTool.box(StringTool.string2Int(cPerm))));
        }

        List<Perm> userPermList = jpaQuery.orderBy(new OrderSpecifier<>(Order.ASC, qPerm.pid)).fetch();

        Map<Long, Perm> permMap = new HashMap<>();
        for (Perm perm : userPermList) {
            //清除缓存
            perm.setSubPerms(null);
            permMap.put(perm.getId(), perm);
        }
        List<Perm> perms = new ArrayList<>();

        for (Perm perm : userPermList) {
            if(perm.getPid() != null && perm.getPid() > 0){
                Perm parent = permMap.get(perm.getPid());
                if(parent.getSubPerms() == null){
                    parent.setSubPerms(new ArrayList<>());
                }
                parent.getSubPerms().add(perm);
            }else {
                perms.add(perm);
            }

        }

        return perms;

    }

    @Override
    public void save(Perm perm) throws Exception{
        super.save(perm);
        Role admin = roleService.findById(ConstantRole.ROLE_ADMIN);
        admin.setPerm(admin.getPerm()+","+perm.getId());
        roleService.save(admin);
    }

    /**
     * 删除菜单及其子菜单
     * @param id
     * @return
     * @throws Exception
     */
    public void deletePerm(Long id) throws Exception{
        log.info("===删除 id 为[" + id + "]的菜单及其下级菜单===");

        List<Perm> subperms = this.selectSubPerms(id);
        for(Perm perm:subperms){
            if(this.selectSubPerms(perm.getId()).size() == 0){
                super.deleteById(perm.getId());
            }else {
                deletePerm(perm.getId());
            }
        }
        super.deleteById(id);
    }

    /**
     * 查询对应 pid 的子菜单
     * @param pid
     * @return
     * @throws Exception
     */
    public List<Perm> selectSubPerms(Long pid) throws Exception{
        log.info("===根据 pid [" + pid + "]获得其对应区域===");
        return queryFactory.select(qPerm).from(qPerm)
                .where(qPerm.valid.eq(true).and(qPerm.pid.eq(pid)))
                .fetch();
    }
}
